#pragma once

namespace API {
namespace Win32 {

//////////////////////////////////////////////////////////////////////
// Notify Icon Data
//////////////////////////////////////////////////////////////////////

class CNotifyIconData : public NOTIFYICONDATA
{
public:	
	CNotifyIconData()
	{
		Clear();
	}

	void Init(HWND hWnd, UINT uID)
	{
		this->hWnd = hWnd;
		this->uID = uID;
	}

	void Clear()
	{
		ZeroMemory(this, sizeof(NOTIFYICONDATA));
		cbSize = sizeof(NOTIFYICONDATA);
	}

	void SetIcon(HICON hIcon)
	{
		SetFlag(NIF_ICON, NULL != hIcon);

		this->hIcon = hIcon;
	}

	void SetCallbackMessage(UINT uCallbackMessage)
	{
		SetFlag(NIF_MESSAGE, uCallbackMessage);

		this->uCallbackMessage = uCallbackMessage;
	}

	void SetTip(LPCTSTR pszTip)
	{
		SetFlag(NIF_TIP, NULL != pszTip);

		if (pszTip)
			_tcsncpy_s(szTip, pszTip, sizeof(szTip)/sizeof(TCHAR)-1);
		else
			szTip[0] = 0;
	}

	void SetBalloonTip(LPCTSTR pszInfoTitle, LPCTSTR pszInfo, DWORD dwInfoFlags = NIIF_NONE, UINT uTimeout = 10)
	{
		SetFlag(NIF_INFO, pszInfoTitle && pszInfo);

		if (pszInfoTitle)
			_tcsncpy_s(szInfoTitle, pszInfoTitle, sizeof(szInfoTitle)/sizeof(TCHAR)-1);
		else
			szInfoTitle[0] = 0;

		if (pszInfo)
			_tcsncpy_s(szInfo, pszInfo, sizeof(szInfo)/sizeof(TCHAR)-1);
		else
			szInfo[0] = 0;
	}

protected:
	void SetFlag(UINT uFlag, BOOL bSet)
	{
		if (bSet)
			uFlags |= uFlag;
		else
			uFlags &= ~uFlag;
	}
};

//////////////////////////////////////////////////////////////////////
// Tray Icon
//////////////////////////////////////////////////////////////////////

class CTrayIcon
{
protected:
	CNotifyIconData m_nid;

public:
	CTrayIcon(void)
	{
	}

	~CTrayIcon(void)
	{
		DestroyTray();
	}

	BOOL InitTray(HWND hWnd, UINT uID, UINT uCallbackMessage, HICON hIcon, LPCTSTR pszTip = NULL)
	{
		ATLASSERT(!m_nid.hWnd && !m_nid.uID);

		m_nid.Init(hWnd, uID);
		m_nid.SetCallbackMessage(uCallbackMessage);
		m_nid.SetIcon(hIcon);
		m_nid.SetTip(pszTip);

		if (Shell_NotifyIcon(NIM_ADD, &m_nid))
			return TRUE;

		m_nid.Clear();
		return FALSE;
	}

	BOOL DestroyTray()
	{
		if (!m_nid.hWnd)
			return FALSE;

		if (!Shell_NotifyIcon(NIM_DELETE, &m_nid))
			return FALSE;

		m_nid.Clear();
		return TRUE;
	}

	BOOL SetTrayIcon(HICON hIcon)
	{
		m_nid.SetIcon(hIcon);

		return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
	}

	BOOL SetTrayTooltip(LPCTSTR pszTip)
	{
		m_nid.SetTip(pszTip);

		return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
	}
};

//////////////////////////////////////////////////////////////////////

}; //namespace Win32
}; //namespace API
